package metricstore

import (
	"gitee.com/shipnet/flogo-common/metric"
	"github.com/project-flogo/core/data/coerce"
)

// Settings settings
type Settings struct {
	Addr      string `md:"addr,required" json:"addr,omitempty"`
	DB        int    `md:"db,required" json:"db,omitempty"`
	Password  string `md:"password" json:"password,omitempty"`
	KeyPrefix string `md:"keyPrefix" json:"keyPrefix,omitempty"`
}

// Input input
type Input struct {
	Op       string        `md:"op,required" json:"op,omitempty"`
	MetricID string        `md:"metricId" json:"metricId,omitempty"`
	Data     metric.Metric `md:"data" json:"data,omitempty"`
}

// ToMap input to map
func (r *Input) ToMap() map[string]interface{} {
	return map[string]interface{}{
		"op":       r.Op,
		"metricId": r.MetricID,
		"data":     toMap(r.Data),
	}
}

// FromMap input from map
func (r *Input) FromMap(values map[string]interface{}) error {
	op, err := coerce.ToString(values["op"])
	if err != nil {
		return err
	}
	r.Op = op

	metricID, err := coerce.ToString(values["metricId"])
	if err != nil {
		return err
	}
	r.MetricID = metricID

	m, err := coerce.ToObject(values["data"])
	if err != nil {
		return err
	}
	data, err := fromMap(m)
	if err != nil {
		return err
	}
	r.Data = data

	return nil
}

// Output output
type Output struct {
	Err  string        `md:"err" json:"err,omitempty"`
	Data metric.Metric `md:"data" json:"data,omitempty"`
}

// ToMap output to map
func (r *Output) ToMap() map[string]interface{} {
	return map[string]interface{}{
		"err":  r.Err,
		"data": toMap(r.Data),
	}
}

// FromMap output from map
func (r *Output) FromMap(values map[string]interface{}) error {
	str, err := coerce.ToString(values["err"])
	if err != nil {
		return err
	}
	r.Err = str

	m, err := coerce.ToObject(values["data"])
	if err != nil {
		return err
	}
	data, err := fromMap(m)
	if err != nil {
		return err
	}
	r.Data = data

	return nil
}

func toMap(m metric.Metric) map[string]interface{} {
	return m.ToMap()
}

func fromMap(values map[string]interface{}) (metric.Metric, error) {
	m, err := metric.MapToMetric(values)
	return *m, err
}
